KDOC 94: 2>&1の意味
この文書のステータス
- 作成
- 2024-02-14 貴島
- レビュー
- 2024-02-18 貴島
概要
Shellに、標準出力と標準エラーをまとめる 2>&1
という書き方がある。よくコマンドの実行結果を保存するのに使う。標準出力と、標準エラー出力をまとめて取り出せるとデバッグに便利である。よくわからずに使っていたので、記法の意味を分解して理解する。
動かしてみる
まず使い方をまとめ、実行して分解を試みる。
result=`echo "hello" 2>&1` echo $result
hello
result=`aaa 2>&1` echo $result
/bin/bash: line 1: aaa: command not found
result=`aaa 2>1` cat 1
/bin/bash: line 1: aaa: command not found
result=`aaa 2>& 1` echo $result
/bin/bash: line 1: aaa: command not found
result=`aaa 2> &1` echo $result
結論、 2>&
はスペースを許容せずひと塊でないといけない。意味的にもひと塊になっているはずだが、意味のつながりがよくわからない。
調べる
Bashのリダイレクト(`>`と`>&`)とパイプ等についてのまとめ #Bash - Qiitaを見てみよう。
>
はリダイレクト記法である。空のファイルを生成して書き込む。書式は $ コマンド [元fd=1]> 先ファイル名
となっている。ファイルディスクリプタ番号はデフォルトで1(標準出力)。
echo "hello1" > test.log cat test.log echo "hello2" 1> test.log cat test.log
hello1 hello2
aaa 2> error.log cat error.log
/bin/bash: line 1: aaa: command not found
>&
は他のファイルディスクリプタにリダイレクトする。 $コマンド [元FD]>&[先FD]
。&がないとファイル書き込みになってしまう。つまり 2>&1
は標準エラー出力を標準出力にリダイレクトする。結果、標準出力に標準出力と標準エラー出力が表示できる。
result=`echo hello 2>&1` echo $result
hello
result=`aaa 2>&1` echo $result
/bin/bash: line 1: aaa: command not found
リダイレクトをさらにリダイレクトできる。
result=`echo hello 2>&1 > aaa.log` cat aaa.log
hello
result=`echo hello 2>&1 > /dev/null` echo $result
以上より、 2>&
がひと塊でないといけない理由。
2>
の数字はリダイレクト元ファイルディスクリプタ指定。>
は1>
が省略されているだけで、1以外には2>
と省略せずに書く必要がある。そもそもスペースは入れない記法である>&
の&
は続くリダイレクト先がファイルディスクリプタであることを示す。>
に続く識別子がファイル名でないのを区別するための記法なので、スペースを許容しないほうが意味が明確である。ファイル名は&
がくる可能性があり、そのとき意味が不明瞭になる
関連
なし。